#include "mesh.h"
#include <assert.h>

namespace ZH
{
	Mesh::Mesh(const std::string& name)
		: m_Name(name),
		m_IndexNumber(0),
		m_VertexStrip(0),
		m_VertexNumber(0),
		m_pDeclaration(NULL),
		m_pVertexBuffer(NULL),
		m_pIndexBuffer(NULL),
		m_Primitive(D3DPT_FORCE_DWORD)
	{
	}

	Mesh::~Mesh()
	{
		if (m_pDeclaration)
			m_pDeclaration->Release();
		m_pDeclaration = NULL;

		if (m_pVertexBuffer)
			m_pVertexBuffer->Release();
		m_pVertexBuffer = NULL;

		if (m_pIndexBuffer)
			m_pIndexBuffer->Release();
		m_pIndexBuffer = NULL;
	}

	Mesh* Mesh::Clone()const
	{
// 		Mesh* pMesh = new Mesh();
// 		pMesh->m_IndexNumber	= m_IndexNumber;
// 		pMesh->m_VertexNumber	= m_VertexNumber;
// 		pMesh->m_VertexStrip	= m_VertexStrip;
// 		pMesh->m_pDeclaration	= m_pDeclaration;
// 		pMesh->m_pIndexBuffer	= m_pIndexBuffer;
// 		pMesh->m_pVertexBuffer	= m_pVertexBuffer;
// 		pMesh->m_Primitive		= m_Primitive;
// 		m_pDeclaration->AddRef();
// 		m_pIndexBuffer->AddRef();
// 		m_pVertexBuffer->AddRef();

		return NULL;
	}

	bool Mesh::DrawPrimitive(LPDIRECT3DDEVICE9 device)
	{
		device->SetVertexDeclaration(m_pDeclaration);
		device->SetStreamSource(0, m_pVertexBuffer, 0, m_VertexStrip);
		device->SetIndices(m_pIndexBuffer);
		device->DrawIndexedPrimitive(m_Primitive, 0, 0, m_VertexNumber, 0, GetPrimitiveNumber());
		return true;
	}

	size_t Mesh::GetVertexNumber()const
	{
		return m_VertexNumber;
	}

	size_t Mesh::GetIndexNumber()const
	{
		return m_IndexNumber;
	}

	size_t Mesh::GetTriangleNumber()const
	{
		switch(m_Primitive)
		{
		case D3DPT_TRIANGLESTRIP:
		case D3DPT_TRIANGLEFAN:
			return m_IndexNumber - 2;
		case D3DPT_TRIANGLELIST:
			return m_IndexNumber / 3;
		default:
			assert(false);
		}
		return 0;
	}

	size_t Mesh::GetPrimitiveNumber()const
	{
		switch (m_Primitive)
		{
		case D3DPT_POINTLIST:
			return m_IndexNumber;
		case D3DPT_LINELIST:
		case D3DPT_LINESTRIP:
			return m_IndexNumber - 1;
		case D3DPT_TRIANGLESTRIP:
		case D3DPT_TRIANGLEFAN:
			return m_IndexNumber - 2;

		case D3DPT_TRIANGLELIST:
			return m_IndexNumber / 3;

		default:
			assert(false);
		}
		return 0;
	}

	RenderPass* Mesh::GetPass()
	{
		return &m_Pass;
	}

	const RenderPass* Mesh::GetPass()const
	{
		return &m_Pass;
	}

	const std::string& Mesh::GetName()const
	{
		return m_Name;
	}
}	// end of namespace ZH
